package org.lazycoder.logger.module.ask3;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Observable;
import java.util.Scanner;
import java.util.Vector;

/**
 * A file watcher will update a observer whenever a pattern is added to the
 * file. (i'm pretty sure file deletions will screw with the current
 * implementation).
 * 
 * @author Matthew Bayliss
 * 
 */
public class FileWatcher extends Observable implements Runnable {
	private Date last;
	private Scanner scanner;
	private FileInputStream input;
	private String buffer = "";
	private BufferedReader reader;
	private final Vector<String> tokens;
	private final SimpleDateFormat newDateParser;
	private String file = "";
	/**
	 * This is used as a separator between log entries, this matches the START
	 * of the NEXT log.
	 */
	private final String regexEntry = "(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d{2}, \\d{4} .*";

	/**
	 * Construct a new file watcher on file, remember to set an observer and
	 * run, otherwise this is useless.
	 * 
	 * @param file
	 *            the file to watch.
	 * @throws FileNotFoundException
	 *             if the file doesn't exist.
	 */
	public FileWatcher(String file) throws FileNotFoundException {
		last = new Date();
		newDateParser = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a");// ("dd-MMM-yyyy HH:mm:ss");
		this.file = file;
		tokens = new Vector<String>();
	}

	/**
	 * Close the file handler.
	 */
	public void close() {
		try {
			reader.close();
			input.close();
			last = null;
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public void run() {
		try {
			scanner = new Scanner(new File(file));
			while (scanner.hasNextLine()) {
				String line = scanner.nextLine();
				if (line.matches(regexEntry)) {
					if (buffer != "") {
						String date = buffer.substring(0, 24);
						if (isNew(date)) {
							last = newDateParser.parse(date);
							tokens.add(buffer);
							setChanged();
							notifyObservers(buffer);
						}
					}
					buffer = line;
				} else {
					buffer = buffer.concat(line);
				}
			}
		} catch (FileNotFoundException e) {
			// We already made sure the file exists.
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		}
	}

	private boolean isNew(String date) {
		try {
			Date newDate = newDateParser.parse(date);
			if (newDate.after(last)) {
				newDate = last;
				return true;
			} else {
				return false;
			}
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return false;
	}

}
